home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / netprog.zip / NETPROG.TAR / lib / pty.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  2KB  |  78 lines

  1. /*
  2.  * Pseudo-terminal routines for 4.3BSD.
  3.  */
  4.  
  5. #include    <sys/types.h>
  6. #include    <sys/stat.h>
  7. #include    <sys/file.h>
  8.  
  9. /*
  10.  * The name of the pty master device is stored here by pty_master().
  11.  * The next call to pty_slave() uses this name for the slave.
  12.  */
  13.  
  14. static char    pty_name[12];    /* "/dev/[pt]tyXY" = 10 chars + null byte */
  15.  
  16. int            /* returns the file descriptor, or -1 on error */
  17. pty_master()
  18. {
  19.     int        i, master_fd;
  20.     char        *ptr;
  21.     struct stat    statbuff;
  22.     static char    ptychar[] = "pqrs";            /* X */
  23.     static char    hexdigit[] = "0123456789abcdef";    /* Y */
  24.  
  25.     /*
  26.      * Open the master half - "/dev/pty[pqrs][0-9a-f]".
  27.      * There is no easy way to obtain an available minor device
  28.      * (similar to a streams clone open) - we have to try them
  29.      * all until we find an unused one.
  30.      */
  31.  
  32.     for (ptr = ptychar; *ptr != 0; ptr++) {
  33.         strcpy(pty_name, "/dev/ptyXY");
  34.         pty_name[8] = *ptr;    /* X */
  35.         pty_name[9] = '0';    /* Y */
  36.  
  37.         /*
  38.          * If this name, "/dev/ptyX0" doesn't even exist,
  39.          * then we can quit now.  It means the system doesn't
  40.          * have /dev entries for this group of 16 ptys.
  41.          */
  42.  
  43.         if (stat(pty_name, &statbuff) < 0)
  44.             break;
  45.  
  46.         for (i = 0; i < 16; i++) {
  47.             pty_name[9] = hexdigit[i];    /* 0-15 -> 0-9a-f */
  48.             if ( (master_fd = open(pty_name, O_RDWR)) >= 0)
  49.                 return(master_fd);    /* got it, done */
  50.         }
  51.     }
  52.     return(-1);    /* couldn't open master, assume all pty's are in use */
  53. }
  54.  
  55. /*
  56.  * Open the slave half of a pseudo-terminal.
  57.  * Note that the master half of a pty is a single-open device,
  58.  * so there isn't a race condition between opening the master
  59.  * above and opening the slave below.  The only way the slave
  60.  * open will fail is if someone has opened the slave without
  61.  * first opening the master.
  62.  */
  63.  
  64. int            /* returns the file descriptor, or -1 on error */
  65. pty_slave(master_fd)
  66. int    master_fd;        /* from pty_master() */
  67. {
  68.     int    slave_fd;
  69.  
  70.     pty_name[5] = 't';    /* change "/dev/ptyXY" to "/dev/ttyXY" */
  71.     if ( (slave_fd = open(pty_name, O_RDWR)) < 0) {
  72.         close(master_fd);
  73.         return(-1);
  74.     }
  75.  
  76.     return(slave_fd);
  77. }
  78.